<script setup>
import {Check, Document} from "@element-plus/icons-vue";
import {computed, reactive, ref} from "vue";
import {Delta, Quill, QuillEditor} from "@vueup/vue-quill";
import ImageResize from "quill-image-resize-vue";
import { ImageExtend, QuillWatch } from "quill-image-super-solution-module";
import axios from "axios";
import {accessHeader, get, post} from "@/net";
import {ElMessage} from "element-plus";
// import ColorDot from "@/components/ColorDot.vue";
import {useStore} from "@/store";
// 导入quill的默认主题
import '@vueup/vue-quill/dist/vue-quill.snow.css';
import ColorDot from "@/components/ColorDot.vue";

const store = useStore();

//状态参数
const props = defineProps({
  show: Boolean,
  defaultTitle: {
    default: '',
    type: String
  },
  defaultText: {
    default: '',
    type: String
  },
  defaultType: {
    default: 0,
    type: Number
  },
  submitButton: {
    default: '立即发表主题',
    type: String
  },
  submit: {
    default: (editor, success) => {
      post('/api/forum/create-topic', {
        type: editor.type.id,
        title: editor.title,
        content: editor.text
      }, () => {
        ElMessage.success("帖子发表成功！")
        success()
      })
    },
    type: Function
  }
})

const emit = defineEmits(['close', 'success'])

//初始化状态信息
function initEditor() {
  if(props.defaultText)
    editor.text = new Delta(JSON.parse(props.defaultText))
  else
    refEditor.value.setContents('', 'user')
  editor.title = props.defaultTitle
  editor.type = findTypeById(props.defaultType)
}
function findTypeById(id){
  for (let type of store.forum.types) {
    if(type.id === id)
      return type
  }
}

//editor的引用
const refEditor = ref()
const editor = reactive({
  type:null,
  title: '',
  text: '',
  loading: false
})

//富文本编辑器配置
Quill.register('modules/imageResize', ImageResize)
Quill.register('modules/ImageExtend', ImageExtend)
const editorOption = {
  modules: {
    toolbar: {
      container: [
        "bold", "italic", "underline", "strike","clean",
        {color: []}, {'background': []},
        {size: ["small", false, "large", "huge"]},
        { header: [1, 2, 3, 4, 5, 6, false] },
        {list: "ordered"}, {list: "bullet"}, {align: []},
        "blockquote", "code-block", "link", "image",
        { indent: '-1' }, { indent: '+1' }
      ],
      handlers: {
        'image': function () {
          QuillWatch.emit(this.quill.id)
        }
      }
    },
    imageResize: {
      modules: [ 'Resize', 'DisplaySize' ]
    },
    ImageExtend: {
      action:  axios.defaults.baseURL + '/api/image/cache',
      name: 'file',
      size: 5,
      loading: true,
      accept: 'image/png, image/jpeg',
      response: (resp) => {
        if(resp.data) {
          return axios.defaults.baseURL + '/images' + resp.data
        } else {
          return null
        }
      },
      methods: 'POST',
      headers: xhr => {
        xhr.setRequestHeader('Authorization', accessHeader().Authorization);
      },
      start: () => editor.uploading = true,
      success: () => {
        ElMessage.success('图片上传成功!')
        editor.uploading = false
      },
      error: () => {
        ElMessage.warning('图片上传失败，请联系管理员!')
        editor.uploading = false
      }
    }
  }
}


//提交帖子
function submitTopic() {
  const text = deltaToText(editor.text)
  //校验
  if(text.length > 20000) {
    ElMessage.warning('字数超出限制，无法发布主题！')
    return
  }
  if(!editor.title) {
    ElMessage.warning('请填写标题！')
    return
  }
  if(!editor.type) {
    ElMessage.warning('请选择一个合适的帖子类型！')
    return
  }
  //发表
  props.submit(editor, () => emit('success'))
}
function deltaToText(delta) {
  if(!delta.ops) return ""
  let str = ""
  for (let op of delta.ops)
    str += op.insert
  return str.replace(/\s/g, "")
}
const contentLength = computed(()=>deltaToText(editor.text).length)

</script>

<template>
  <div>
    <el-drawer
        :model-value="show"
        :direction="'btt'"
        :size="650"
        :close-on-click-modal="false"
        @open="initEditor"
        @close="emit('close')">
      <template #header>
        <div>
          <div style="font-weight: bold">发表新的帖子</div>
          <div style="font-size: 13px">注意：帖子内容务请必遵守相关法律规定，禁止散布任何不实信息危害他人权利</div>
        </div>
      </template>
      <div style="display: flex;gap: 10px">
        <div style="width: 150px">
          <el-select placeholder="选择主题类型..." value-key="id" v-model="editor.type" :disabled="!store.forum.types.length">
            <el-option v-for="item in store.forum.types.filter(type => type.id > 0)" :value="item" :label="item.name">
              <div>
                <color-dot :color="item.color"/>
                <span style="margin-left: 10px">{{item.name}}</span>
              </div>
            </el-option>
          </el-select>
        </div>
        <div style="flex: 1">
          <el-input
              v-model="editor.title"
              placeholder="请输入帖子标题"
              :prefix-icon="Document"/>
        </div>
      </div>
      <div style="margin-top: 10px;font-size: 13px;color: grey">
        <span style="margin-left: 10px">
          <color-dot :color="editor.type ? editor.type.color : '#dedede'"/>
        {{editor.type ? editor.type.desc : "请在上方选择一个帖子类型"}}
        </span>
      </div>
      <div style="margin-top: 15px;height: 440px"
            v-loading="editor.uploading"
            element-loading-text="正在上传图片...">
        <quill-editor v-model:content="editor.text" style="height: calc(100% - 45px);overflow: hidden;border-radius: 10px"
                      content-type="delta"
                      ref="refEditor"
                      placeholder="今天想分享点什么呢？"
                      :options="editorOption"/>
      </div>
      <div style="display:flex;justify-content: space-between;margin-top: 10px">
        <div style="color: grey; font-size: 13px">
          当前字数 {{contentLength}} （最大支持100000字）
        </div>
        <div>
          <el-button type="success" plain :icon="Check" @click="submitTopic">{{props.submitButton}}</el-button>
        </div>

      </div>

    </el-drawer>
  </div>
</template>

<style scoped>
:deep(.el-drawer) {
  width: 800px;
  margin: auto;
  border-radius: 20px;
}
:deep(.el-drawer__header) {
  margin: 0;
}
:deep(.ql-toolbar){
  border-radius: 10px 10px 0 0;
  border-color: var(--el-border-color);
}
:deep(.ql-container){
  border-radius: 0 0 10px 10px;
  border-color: var(--el-border-color);
}
:deep(.ql-editor){
  font-size: 14px;
}
:deep(.ql-editor.ql-blank::before) {
  color: var(--el-text-color-placeholder);
  font-style: normal;
}

</style>